﻿#include "serial_file_base.h"
#include  "fcntl.h"
CSerialFileBase::CSerialFileBase()
{
	m_fileSize = SIZE_MB(128);
	m_baseLBA  = 2048;

	m_bRecordWtTime = false;
	m_access_mod = -1;
	m_pLock = NULL;

	m_align_buf = new unsigned char[SIZE_HDD_BLOCK1];
	memset(m_align_buf,0,SIZE_HDD_BLOCK1);

	m_cache_buf = new unsigned char[SIZE_HDD_BLOCK1];
	memset(m_cache_buf,0,SIZE_HDD_BLOCK1);
	m_cache_pos  = 0;
	m_cur_offset = 0;
	m_sec_size    = SIZE_HDD_BLOCK1;
	m_lastRet     = 0;
	memset(m_storage_file,0,60);
}

CSerialFileBase::~CSerialFileBase()
{
	if(m_align_buf)
	{
		delete [] m_align_buf;
	}

	if(m_cache_buf)
	{
		delete [] m_cache_buf;
	}
}

int CSerialFileBase::CopyFile(CSerialFileBase * src, CSerialFileBase * dest,uint32_t appoint_bufsz)
{
	CROSS_ASSERT(appoint_bufsz != 0);
	CROSS_ASSERT(src != NULL);
	CROSS_ASSERT(dest!= NULL);

    TRACE("appoint_bufsz %d src %s dest %s \n",appoint_bufsz,src->get_device_name(),dest->get_device_name());
	if(appoint_bufsz < (128 <<10))
	{
		appoint_bufsz = 128 <<10;
	}
	uchar_t * pBuf = new uchar_t[appoint_bufsz];
	int  ret = 0;
	int ioSize = appoint_bufsz;
	uint32_t ioPos = 0;
	uint32_t dataSize = src->get_data_size();
	bool blast        = false;

	while ( 0 != dataSize)
	{
		if(dataSize > appoint_bufsz)
		{
			ioSize = appoint_bufsz;
		}
		else
		{
			ioSize = dataSize;
			blast = true;
		}

		ret =  src->ReadPos(ioPos,pBuf,ioSize);
		if(ret < 0)
		{
			TRACE_ERR("Read fail src file pos %d size %d ret %d .\n",ioPos,ioSize,ret);
			break;
		}

		ret =  dest->WritePos(ioPos,pBuf,ioSize);
		if(ret < 0)
		{
			TRACE_ERR("Write fail dest file pos %d size %d ret %d .\n",ioPos,ioSize,ret);
			break;
		}

		if(blast)
		{
			break;
		}

		if(ioPos < (2 <<20))
		{
			TRACE("copy data  dataSize %d offset %d  .\n",dataSize,ioPos);
		}

		if(ioPos + (2 <<20) > src->get_data_size())
		{
			TRACE("copy data  dataSize %d offset %d  .\n",dataSize,ioPos);
		}

		dataSize -= appoint_bufsz;
		ioPos += appoint_bufsz;
		CrossSleep(100);
	}

	delete [] pBuf;
	return ret;
}

int CSerialFileBase::CopyFileBySize(CSerialFileBase * src, CSerialFileBase * dest,uint32_t appoint_bufsz,uint32_t appoint_sz)
{
	CROSS_ASSERT(appoint_bufsz != 0);
	CROSS_ASSERT(src != NULL);
	CROSS_ASSERT(dest!= NULL);

	TRACE("appoint_bufsz %d src %s dest %s \n",appoint_bufsz,src->get_device_name(),dest->get_device_name());
	uchar_t * pBuf = new uchar_t[appoint_bufsz];
	int  ret = 0;
	int ioSize = appoint_bufsz;
	uint32_t ioPos = 0;
	uint32_t dataSize = src->get_data_size();
	if(dataSize > appoint_sz)
	{
		dataSize = appoint_sz;
	}

	bool blast        = false;
	while ( 0 != dataSize)
	{
		if(dataSize > appoint_bufsz)
		{
			ioSize = appoint_bufsz;
		}
		else
		{
			ioSize = dataSize;
			blast = true;
		}

		ret =  src->ReadPos(ioPos,pBuf,ioSize);
		if(ret < 0)
		{
			TRACE_ERR("Read fail src file pos %d size %d ret %d .\n",ioPos,ioSize,ret);
			break;
		}

		ret =  dest->WritePos(ioPos,pBuf,ioSize);
		if(ret < 0)
		{
			TRACE_ERR("Write fail dest file pos %d size %d ret %d .\n",ioPos,ioSize,ret);
			break;
		}

		if(blast)
		{
			break;
		}

		if(ioPos < (2 <<20))
		{
			TRACE("copy data  dataSize %d offset %d  .\n",dataSize,ioPos);
		}

		if(ioPos + (2 <<20) > src->get_data_size())
		{
			TRACE("copy data  dataSize %d offset %d  .\n",dataSize,ioPos);
		}

		dataSize -= appoint_bufsz;
		ioPos += appoint_bufsz;
		CrossSleep(100);
	}

	delete [] pBuf;
	return ret;
}

int CSerialFileBase::AllocSpace(const char * filePath,uint32_t fileSpace)
{
	int fd = open(filePath, O_RDWR|O_CREAT, 0666);
	if (fd < 0)
	{
		fd = open(filePath, O_RDWR|O_CREAT, 0666);
		if(fd < 0) //重试再一次打开
		{
			int err = errno;
			printf("filePath %s Alloc file fail !!! errno %d str %s .\n",filePath,err,strerror(err));
			return ERR_FILE_OPEN;
		}
	}

	lseek(fd,fileSpace-1,SEEK_SET);

	if( 1 != write(fd,"1",1))
	{
		printf("errno %d str %s .\n",errno,strerror(errno));
	}

	close(fd);
	return 0;
}

bool CSerialFileBase::IsRawDevice(const char * diskPath)
{
	bool bRaw = false;
#ifdef _WIN32
	//裸磁盘设备
	if(strstr(diskPath,"\\\\.\\PhysicalDrive"))
	{
		bRaw = true;
	}
	else if(strstr(diskPath,":\\"))
	{
		bRaw = false;
	}
#else
    if(strstr(diskPath,"/dev/mmcblk"))//SD裸设备
	{
		bRaw = true;
	}
	else if(strstr(diskPath,"/dev/sd"))//磁盘裸设备
	{
		bRaw = true;
	}
	else
	{
		bRaw = false;
	}
#endif
	return bRaw;
}


